import 'package:flutter/services.dart';
import 'package:share_fit/app/tools/log_utils.dart';
import 'package:share_fit/app/ute/uteped_const.dart';
import 'package:share_fit/app/ute/uteped_device.dart';
import 'package:share_fit/app/ute/uteped_mixin.dart';

abstract class UTEPedListener {
  /// 原生端回调函数 `onRemoteEvent`
  /// 原生端返回事件 [event]
  /// 原生端返回所请求的方法 [method]
  void onRemoteEvent(event, method);
  void onRemoteError(error);
}

class UTEPedHelper {

  static const eventChannel = EventChannel('uteped_sdk/event');

  static List<UTEPedListener> listeners = [];

  static void init() {
    _initChannel();
    UTEPedDevice.instance.init();
    addListener(UTEPedDevice.instance);
  }

  static void _initChannel() {
    logger.d("init channel...");
    eventChannel.receiveBroadcastStream().listen((event) {
      logger.d("receive from remote:$event");
      onRemoteEvent(event);
    }, onDone: () {
      logger.d("onDone");
    }, onError: (error) {
      logger.d("failed: $error");
      onRemoteError(error);
    });
  }

  static void onRemoteEvent(event) {
    var method = event[UTEPedConst.keyMethod];
    List<UTEPedListener> copyListener = List.from(listeners);
    for (var listener in copyListener) {
      var uteMixin = listener as UTEPedMixin;
      var isMethodSupport = uteMixin.useMethodSupport() && uteMixin.getSupportedMethods().contains(method);
      if (uteMixin.getRemotePath() == event[UTEPedConst.keyPath] || isMethodSupport) {
        try {
          listener.onRemoteEvent(event, method);
        } catch(e) {
          logger.d(e);
        }
      }
    }
  }

  static void onRemoteError(error) {
    for (var listener in listeners) {
      try {
        listener.onRemoteError(error);
      } catch(e) {
        logger.d(e);
      }
    }
  }

  static void addListener(UTEPedListener listener) {
    if (listeners.contains(listener)) {
      return;
    }

    listeners.add(listener);
  }

  static void removeListener(UTEPedListener listener) {
    if (listeners.contains(listener)) {
      listeners.remove(listener);
    }
  }
}